import React, { useState, useEffect, useRef } from 'react';
import { Card, Table, Button, message, Modal, Form, FormInstance } from 'antd';
import { PlusOutlined, ArrowRightOutlined } from '@ant-design/icons';
import { AxiosResponse } from 'axios';
import { reqCategory, DataStatus, reqAddCategory, reqUpdateCategory } from '../../api';
import AddForm from './AddForm';
import UpdateForm from './UpdateForm';

type DataSource = {
    "parentId": string;
    "_id": string;
    "name": string;
    "__v": number;
};
type Status = {
    status: DataStatus.sucess;
    data: DataSource[];
} | {
    status: DataStatus.failure;
    msg: string;
};
type Columns = [{
    title: string,
    dataIndex: string;
}, {
    width: string | number;
    title: string;
    render: (category: DataSource) => React.ReactNode;
}];
type IdAndName = {
    parentId: string;
    parentName: string;
};

enum ModelBox {
    hide,
    showAdd,
    showUpdate
}

// 商品分类路由组件
const Category: React.FC = () => {
    const [categorys, setCategorys] = useState<DataSource[]>([]);
    const [subCategorys, setSubCategorys] = useState<DataSource[]>([]);
    const [isLoading, setLoading] = useState<boolean>(false);
    const [{ parentId, parentName }, setIdAndName] = useState<IdAndName>({ parentId: '0', parentName: '' });
    const [modalVisible, setModalVisible] = useState<ModelBox>(ModelBox.hide);
    const dataRef = useRef<DataSource>();
    const addCategorysRef = useRef<FormInstance>(null);
    const [form] = Form.useForm();
    const handleFirstCategorys = (): void => {
        setIdAndName({ parentId: '0', parentName: '' });
        setSubCategorys([]);
    };
    const handleSubCategorys = (category: DataSource): void => {
        setIdAndName({
            parentId: category._id,
            parentName: category.name
        });
    };
    const toggleModal = (toggle: ModelBox): void => {
        setModalVisible(toggle);
    };
    const addCategorys = async (): Promise<void> => {
        const { parentId, parentName }: { parentId: string, parentName: string } = addCategorysRef.current!.getFieldsValue();
        if (!parentName?.trim()) return;
        toggleModal(ModelBox.hide);
        const { data }: AxiosResponse<{
            status: DataStatus.sucess;
            data: DataSource;
        } | {
            status: DataStatus.failure;
            msg: string;
        }> = await reqAddCategory(parentName, parentId);
        if (data.status === DataStatus.sucess) {
            message.success('添加成功!');
            parentId === '0'
                ? setCategorys([...categorys, data.data])
                : setSubCategorys([...subCategorys, data.data]);
            return;
        }
        message.error(data.msg);
    };
    const updateCategorys = async (): Promise<void> => {
        const { _id, parentId }: DataSource = dataRef.current!;
        const categoryName: string = form.getFieldValue('categoryName');
        if (!categoryName?.trim()) return;
        toggleModal(ModelBox.hide);
        const { data }: AxiosResponse<{ status: DataStatus.sucess } | { status: DataStatus.failure, msg: string }> = await reqUpdateCategory({ categoryId: _id, categoryName });
        if (data.status === DataStatus.sucess) {
            message.success('更新成功!');
            setIdAndName({ parentId, parentName: categoryName });
            return;
        }
        message.error(data.msg);
    };
    const Plus: React.ReactNode = <Button type="primary" icon={<PlusOutlined />} onClick={() => toggleModal(ModelBox.showAdd)}>添加</Button>;
    const columns: Columns = [
        {
            title: '分类名称',
            dataIndex: 'name',
        },
        {
            width: 360,
            title: '操作',
            render(category) {
                return (
                    <span>
                        <Button type="link" onClick={() => {
                            dataRef.current = category;
                            toggleModal(ModelBox.showUpdate);
                        }}>修改分类</Button>
                        {
                            parentId === '0'
                            && <Button type="link" onClick={() => handleSubCategorys(category)}>查看子分类</Button>
                        }
                    </span>
                );
            }
        }
    ];
    useEffect(() => {
        const handleAsyncCategory = async (): Promise<void> => {
            try {
                const { data }: AxiosResponse<Status> = await reqCategory(parentId);
                setLoading(false);
                if (data.status === DataStatus.sucess) {
                    parentId === '0'
                        ? setCategorys(data.data)
                        : setSubCategorys(data.data);
                    return;
                }
                message.error(data.msg);
            } catch {
                setLoading(false);
            }
        };
        setLoading(true);
        handleAsyncCategory();
    }, [parentId, parentName]);
    return (
        <Card title={
            parentId === '0'
                ? '一级分类列表'
                : (
                    <span>
                        <Button type="link" onClick={handleFirstCategorys}>一级分类列表</Button>
                        <ArrowRightOutlined style={{ marginRight: 10 }} />
                        {parentName}
                    </span>
                )
        } extra={Plus}>
            <Modal destroyOnClose title="添加分类" visible={modalVisible === ModelBox.showAdd} onOk={addCategorys} onCancel={() => toggleModal(ModelBox.hide)} okText="确认" cancelText="取消">
                <AddForm addCategorysRef={addCategorysRef} parentId={parentId} categorys={categorys} />
            </Modal>
            <Modal destroyOnClose title="更新分类" visible={modalVisible === ModelBox.showUpdate} onOk={updateCategorys} onCancel={() => toggleModal(ModelBox.hide)} okText="确认" cancelText="取消">
                <UpdateForm form={form} categoryName={dataRef.current?.name} />
            </Modal>
            <Table bordered loading={isLoading} pagination={{
                defaultPageSize: 5,
                showQuickJumper: true
            }} rowKey="_id" dataSource={parentId === '0' ? categorys : subCategorys} columns={columns} />
        </Card>
    );
};

export default Category;